package main

import (
	"context"
	"fmt"
)

func main() {
	//WithCancel 返回带有新的 Done 频道的 parent 的副本。 当调用返回的取消函数或父上下文的 Done 通道关闭时，返回的上下文的 Done 通道关闭，以先发生者为准。
	//
	//取消此上下文会释放与其关联的资源，因此一旦此上下文中运行的操作完成，代码应立即调用取消。

	//此示例演示了使用可取消上下文来防止 goroutine 泄漏。 到示例函数结束时，由 gen 启动的 goroutine 将返回而不会泄漏。

	gen := func(ctx context.Context) <-chan int {
		dst := make(chan int)
		n := 1
		go func() {
			for {
				select {
				case <-ctx.Done():
					return
				case dst <- n:
					n++
				}
			}
		}()

		return dst
	}

	ctx, cancel := context.WithCancel(context.Background())
	//ctx, cancel := context.WithTimeout(context.Background(), 100 * time.Microsecond)
	defer cancel()

	for n := range gen(ctx) {
		fmt.Println(n)
		if n == 5 {
			break
		}
	}
	//1
	//2
	//3
	//4
	//5
}
